package com.quiz.quazz.client;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;

import android.util.Log;

import com.quiz.quazz.value.Constants;

/**
 * Description
 * 
 * @author Catalin Prata Date: 2/12/13
 */
public class TcpClient {

	private String playerName;

	// message to send to the server
	private String mServerMessage;

	// sends message received notifications
	private OnMessageReceived mMessageListener = null;

	// while this is true, the server will continue running
	private boolean mRun = false;

	// used to send messages
	private PrintWriter mBufferOut;

	// used to read messages from the server
	private BufferedReader mBufferIn;

	private static TcpClient instance = null;

	public static TcpClient getInstance() {
		if (instance == null) {
			instance = new TcpClient();
		}
		return instance;
	}

	private TcpClient() {
	}

	public void setOnMessageReceivedListener(OnMessageReceived listener) {
		mMessageListener = listener;
	}

	/**
	 * Sends the message entered by client to the server
	 * 
	 * @param message text entered by client
	 */
	public void sendMessage(String message) {
		if (mBufferOut != null && !mBufferOut.checkError()) {
			mBufferOut.println(message);
			mBufferOut.flush();
		}
	}

	/**
	 * Close the connection and release the members
	 */
	public void stopClient() {

		// send mesage that we are closing the connection
		sendMessage(Constants.CLOSED_CONNECTION + "Kazy");

		mRun = false;

		if (mBufferOut != null) {
			mBufferOut.flush();
			mBufferOut.close();
		}

		mMessageListener = null;
		mBufferIn = null;
		mBufferOut = null;
		mServerMessage = null;
	}

	public void run(String serverIp, int serverPort, String playerName) {
		serverPort += 50000;
		this.playerName = playerName;

		mRun = true;

		try {
			// here you must put your computer's IP address.
			InetAddress serverAddr = InetAddress.getByName(serverIp);

			Log.e("TCP Client", "C: Connecting...");

			// create a socket to make the connection with the server
			Socket socket = new Socket(serverAddr, serverPort);

			try {

				// sends the message to the server
				mBufferOut = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);

				// receives the message which the server sends back
				mBufferIn = new BufferedReader(new InputStreamReader(socket.getInputStream()));
				// send login name
				sendMessage(Constants.LOGIN_NAME + this.playerName);

				// in this while the client listens for the messages sent by the server
				while (mRun) {

					mServerMessage = mBufferIn.readLine();

					if (mServerMessage != null && mMessageListener != null) {
						mMessageListener.messageReceived(mServerMessage);
					}

				}

				Log.e("RESPONSE FROM SERVER", "S: Received Message: '" + mServerMessage + "'");

			} catch (Exception e) {

				Log.e("TCP", "S: Error", e);

			} finally {
				// the socket must be closed. It is not possible to reconnect to this socket
				// after it is closed, which means a new socket instance has to be created.
				socket.close();
			}

		} catch (Exception e) {

			Log.e("TCP", "C: Error", e);

		}

	}

	// Declare the interface. The method messageReceived(String message) will must be implemented in the MyActivity
	// class at on asynckTask doInBackground
	public interface OnMessageReceived {
		public void messageReceived(String message);
	}
}